package orbito.entity;

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import orbito.graphics.ViewFocus;
import orbito.graphics.Viewport;
import orbito.util.Vec2;

public class PlanetoidSystem implements ViewFocus {
	
	// The planetoid this system is centered on.
	Planetoid centroid;
	
	// The collection of systems hierarchically below this system.
	Collection<PlanetoidSystem> children;
	
	public PlanetoidSystem(Planetoid centroid) {
		this.centroid = centroid;
		this.children = new LinkedList<PlanetoidSystem>();
	}
	
	public void step(double t, double dt) {
		for (PlanetoidSystem p : children) {
			p.step(t, dt);
		}
		centroid.step(t, dt);
	}
	
	public void render(Graphics2D g, double t, double dt) {
		for (PlanetoidSystem p : children) {
			p.render(g, t, dt);
		}
		centroid.render(g, t, dt);
	}
	
	public void renderInfo(Graphics2D g, Viewport v, AffineTransform tx, double t, double dt) {
		for (PlanetoidSystem p : children) {
			p.renderInfo(g, v, tx, t, dt);
		}
		centroid.renderInfo(g, v, tx, t, dt);
	}
	
	/**
	 * @return A flat-list of all planetoids in this system.
	 */
	public Collection<Planetoid> assembleNodes() {
		Collection<Planetoid> assembled = new LinkedList<Planetoid>();
		
		// Add this system's planetoid.
		assembled.add(centroid);
		
		// Add childrens' planetoid.
		for (PlanetoidSystem s : children) {
			// Set this child's orbital parent.
			s.getCentroid().setOrbitalParent(centroid);
			
			// Assemble and add this child's children.
			for (Planetoid p : s.assembleNodes()) {
				p.setPosition(p.getPosition().add(centroid.getPosition()));
				p.setVelocity(p.getVelocity().add(centroid.getVelocity()));
				p.setOrientation(p.getOrientation() + centroid.getOrientation());
				p.setAngularSpeed(p.getAngularSpeed() + centroid.getAngularSpeed());
				
				assembled.add(p);
			}
		}
		
		return assembled;
	}
	
	public Planetoid getCentroid() {
		return centroid;
	}
	
	public void setCentroid(Planetoid centroid) {
		this.centroid = centroid;
	}
	
	public void addChildSystem(PlanetoidSystem system) {
		children.add(system);
	}
	
	public void addChildSystems(PlanetoidSystem[] children) {
		// Add children from array.
		for (PlanetoidSystem s : children) {
			this.children.add(s);
		}
	}
	
	public Collection<PlanetoidSystem> getChildSystems() {
		return children;
	}
	
	// -------------------------------------------
	// FocusItem Interface.
	
	public String getFocusName() {
		return centroid.getName();
	}
	
	public Vec2 getFocusPosition() {
		return centroid.getPosition();
	}
	
	public List<ViewFocus> getFocusChildren() {
		List<ViewFocus> children = new LinkedList<ViewFocus>();
		for (PlanetoidSystem s : this.children) {
			children.add(s);
		}
		return children;
	}
}
